<template>
  <div class="menu-container">
    <div class="left">
      <el-card shadow="always" style="min-width: 400px">
        <template #header>
          <p>菜单管理</p>
          <el-button size="small" type="primary" @click="addMenuBtn('D')"> 新增一级菜单</el-button>
          <el-button size="small" :disabled="!isTopDir" @click="addMenuBtn('M')">
            新增二级菜单
          </el-button>
        </template>
        <el-tree :data="data" :render-content="render" accordion @node-click="handleNodeClick" />
      </el-card>
    </div>
    <div class="right iScroll">
      <!-- 菜单编辑表单 -->
      <el-card shadow="always">
        <template #header>
          <span style="margin-right: 15px">菜单编辑</span>
          <el-button
            type="primary"
            v-if="editForm.menuType === 'M'"
            plain
            size="small"
            @click="permBtnClick(editForm.id)"
          >
            菜单权限
          </el-button>
        </template>
        <el-alert
          style="margin-bottom: 15px"
          title="点击菜单列表任意一项后，可进行编辑"
          type="info"
        />
        <el-form
          v-if="formShow"
          ref="formRef"
          :rules="menuRules"
          :model="editForm"
          label-width="100px"
        >
          <el-form-item label="菜单ID" prop="id">
            <el-input placeholder="菜单ID" disabled v-model.number="editForm.id"></el-input>
          </el-form-item>
          <el-form-item label="菜单类型" prop="menuType">
            <el-select v-model.trim="editForm.menuType" placeholder="选择菜单类型" disabled>
              <el-option label="目录" value="D" />
              <el-option label="菜单" value="M" />
            </el-select>
          </el-form-item>
          <el-form-item label="菜单名称" prop="menuName">
            <el-input placeholder="菜单名称" v-model.trim="editForm.menuName"></el-input>
          </el-form-item>
          <el-form-item label="路由名称" prop="routerName">
            <el-input placeholder="路由名称" v-model.trim="editForm.routerName"></el-input>
          </el-form-item>
          <el-form-item label="路由路径" prop="routerPath">
            <el-input placeholder="路由路径" v-model.trim="editForm.routerPath"></el-input>
          </el-form-item>
          <el-form-item v-if="editForm.menuType === 'M'" label="组件路径" prop="componentPath">
            <el-input placeholder="组件路径" v-model.trim="editForm.componentPath"></el-input>
          </el-form-item>
          <el-form-item v-if="editForm.menuType === 'M'" label="重定向" prop="isRedirect">
            <el-select v-model.trim="editForm.isRedirect" placeholder="重定向">
              <el-option label="是" value="1" />
              <el-option label="否" value="0" />
            </el-select>
          </el-form-item>
          <el-form-item
            v-if="editForm.isRedirect === '1' && editForm.menuType === 'M'"
            label="重定向路径"
            prop="redirectPath"
          >
            <el-input placeholder="重定向路径" v-model.trim="editForm.redirectPath"></el-input>
          </el-form-item>
          <el-form-item v-if="editForm.menuType === 'M'" label="菜单显示" prop="isShow">
            <el-select v-model.trim="editForm.isShow" placeholder="菜单显示">
              <el-option label="是" value="1" />
              <el-option label="否" value="0" />
            </el-select>
          </el-form-item>
          <el-form-item label="展示排序" prop="sort">
            <el-input placeholder="展示排序" v-model.number="editForm.sort"></el-input>
          </el-form-item>
          <el-form-item label="图标" prop="icon">
            <el-input placeholder="svg文件名称或<svg>代码" v-model.trim="editForm.icon"></el-input>
          </el-form-item>
          <el-form-item label="备注" prop="remark">
            <el-input placeholder="备注" v-model.trim="editForm.remark"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="warning" plain @click="editSave(formRef)">保存</el-button>
            <el-button type="danger" @click="deleteBtn(editForm.id)">删除</el-button>
          </el-form-item>
        </el-form>
      </el-card>
    </div>
    <!-- 右侧栏新增菜单抽屉 -->
    <el-drawer
      v-model="addMenuDrawer"
      :title="'新增' + (isTop ? '一级' : '二级') + '菜单'"
      @close="addCancel"
    >
      <el-form ref="addFormRef" :rules="menuRules" :model="addForm" label-width="100px">
        <el-form-item v-if="!isTop" label="父菜单ID" prop="parentId">
          <el-input placeholder="父菜单ID" disabled v-model.number="addForm.parentId"></el-input>
        </el-form-item>
        <el-form-item v-if="!isTop" label="父菜单名称">
          <el-input placeholder="父菜单名称" disabled v-model.trim="addTwoPName"></el-input>
        </el-form-item>
        <el-form-item label="菜单类型" prop="menuType">
          <el-select placeholder="选择菜单类型" v-model.trim="addForm.menuType" :disabled="!isTop">
            <el-option label="目录" value="D" />
            <el-option label="菜单" value="M" />
          </el-select>
        </el-form-item>
        <el-form-item label="菜单名称" prop="menuName">
          <el-input placeholder="菜单名称" v-model.trim="addForm.menuName"></el-input>
        </el-form-item>
        <el-form-item label="路由名称" prop="routerName">
          <el-input placeholder="路由名称" v-model.trim="addForm.routerName"></el-input>
        </el-form-item>
        <el-form-item label="路由路径" prop="routerPath">
          <el-input placeholder="路由路径" v-model.trim="addForm.routerPath"></el-input>
        </el-form-item>
        <el-form-item v-if="addForm.menuType === 'M'" label="组件路径" prop="componentPath">
          <el-input placeholder="组件路径" v-model.trim="addForm.componentPath"></el-input>
        </el-form-item>
        <el-form-item v-if="addForm.menuType === 'M'" label="重定向" prop="isRedirect">
          <el-select v-model.trim="addForm.isRedirect" placeholder="重定向">
            <el-option label="是" value="1" />
            <el-option label="否" value="0" />
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="addForm.isRedirect === '1' && addForm.menuType === 'M'"
          label="重定向路径"
          prop="redirectPath"
        >
          <el-input placeholder="重定向路径" v-model.trim="addForm.redirectPath"></el-input>
        </el-form-item>
        <el-form-item v-if="addForm.menuType === 'M'" label="菜单显示" prop="isShow">
          <el-select v-model.trim="addForm.isShow" placeholder="菜单显示">
            <el-option label="是" value="1" />
            <el-option label="否" value="0" />
          </el-select>
        </el-form-item>
        <el-form-item label="展示排序" prop="sort">
          <el-input placeholder="展示排序" v-model.number="addForm.sort"></el-input>
        </el-form-item>
        <el-form-item label="图标" prop="icon">
          <el-input placeholder="svg文件名称或<svg>代码" v-model.trim="addForm.icon"></el-input>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input placeholder="备注" v-model.trim="addForm.remark"></el-input>
        </el-form-item>
        <el-form-item>
          <el-button plain @click="addCancel">取消</el-button>
          <el-button type="primary" @click="addSubmit(addFormRef)">提交</el-button>
        </el-form-item>
      </el-form>
    </el-drawer>
    <!-- 权限抽屉 -->
    <el-drawer title="权限" v-model="permDrawer">
      <el-button plain type="primary" size="small" @click="addPermDialog = true"
        >新增权限</el-button
      >
      <el-table max-height="80%" :data="permList" style="width: 100%">
        <el-table-column prop="menuName" label="权限名称" width="110" />
        <el-table-column prop="permission" label="权限代码" width="220" />
        <el-table-column fixed="right" label="操作" min-width="120">
          <template #default="scope">
            <el-link type="primary" @click="editPermBtn(scope.row)">编辑</el-link>
            <el-link type="danger" @click="permDelete(scope.row.id)" style="margin-left: 10px"
              >删除</el-link
            >
          </template>
        </el-table-column>
      </el-table>
    </el-drawer>
    <!-- 新增权限对话框 -->
    <el-dialog v-model="addPermDialog" title="新增权限" style="min-width: 400px; max-width: 500px">
      <el-form ref="form" :model="addPermForm" :rules="addPermFormRule" label-width="auto">
        <el-form-item label="权限名称" prop="menuName">
          <el-input placeholder="权限名称" v-model.trim="addPermForm.menuName"></el-input>
        </el-form-item>
        <el-form-item label="权限代码" prop="permission">
          <el-input placeholder="权限代码" v-model.trim="addPermForm.permission"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="addPermDialogCancel">取消</el-button>
          <el-button type="primary" @click="addPermDialogSubmit"> 提交 </el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 编辑权限对话框 -->
    <el-dialog v-model="editPermDialog" title="修改权限" style="min-width: 400px; max-width: 500px">
      <el-form ref="form" :model="editPermForm" :rules="addPermFormRule" label-width="auto">
        <el-form-item label="权限名称" prop="menuName">
          <el-input placeholder="权限名称" v-model.trim="editPermForm.menuName"></el-input>
        </el-form-item>
        <el-form-item label="权限代码" prop="permission">
          <el-input placeholder="权限代码" v-model.trim="editPermForm.permission"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="editPermDialogCancel">取消</el-button>
          <el-button type="primary" @click="editPermDialogSubmit"> 保存 </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script lang="ts" setup>
import { getMenuTree } from '@/api/system/menu'
import {
  addMenu,
  updateMenu,
  deleterMenu,
  getPermsList,
  addPerm,
  updatePerm
} from '@/api/system/menu'

// 菜单数据
const data = ref<Menu[]>([])

// 获取菜单数据
function toGetMenuTree() {
  getMenuTree().then((res) => {
    data.value = res.data!
  })
}

// 菜单点击
const handleNodeClick = (data: Menu) => {
  if (data.menuType === 'D') {
    isTopDir.value = true
    addTwoPId.value = data.id
    addTwoPName.value = data.menuName
  } else {
    isTopDir.value = false
    addTwoPId.value = -1
    addTwoPName.value = ''
  }
  editForm.value = { ...data }
  formShow.value = true
}

// 树形渲染
function render(
  h: Function,
  {
    data
  }: {
    node: Node
    data: Menu
    store: any
  }
) {
  return h('span', {}, data.menuName)
}
const formShow = ref(false)
const formRef = ref()
// 表单数据
const editForm = ref<Menu>({
  id: 0,
  menuName: '',
  parentId: 0,
  routerPath: '',
  routerName: '',
  componentPath: '',
  isRedirect: '0',
  redirectPath: '',
  menuType: '',
  permission: '',
  createBy: '',
  createTime: '',
  updateBy: '',
  updateTime: '',
  remark: '',
  sort: 0,
  isShow: '1',
  icon: '',
  children: []
})

/**
 * 一级菜单
 */
// 编辑保存
async function editSave(formR: FormInstance | undefined) {
  ElMessageBox.confirm('确认保存做出的修改吗?', '编辑菜单', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(async () => {
      if (!formR) return
      await formR.validate((vaild: boolean) => {
        if (vaild) {
          updateMenu({ ...editForm.value }).then((res) => {
            if (res.code === 200) {
              ElMessage({
                message: '保存成功',
                type: 'success'
              })
              toGetMenuTree()
            }
          })
        } else {
          ElMessage({
            message: '请检查数据',
            type: 'warning'
          })
        }
      })
    })
    .catch(() => {})
}

// 删除 按钮
function deleteBtn(id: number) {
  ElMessageBox.confirm('确认删除选择的菜单吗?', '删除菜单', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'error'
  })
    .then(() => {
      deleterMenu(id).then((res) => {
        if (res.code === 200) {
          ElMessage({
            message: '删除成功',
            type: 'success'
          })
          editForm.value = {
            id: 0,
            menuName: '',
            parentId: 0,
            routerPath: '',
            routerName: '',
            componentPath: '',
            isRedirect: '0',
            redirectPath: '',
            menuType: '',
            permission: '',
            createBy: '',
            createTime: '',
            updateBy: '',
            updateTime: '',
            remark: '',
            sort: 0,
            isShow: '1',
            icon: '',
            children: []
          }
          formShow.value = false
          toGetMenuTree()
        }
      })
    })
    .catch(() => {})
}

// 页面加载
onMounted(() => {
  toGetMenuTree()
})

/**
 * 二级菜单
 */
// 是否是一级目录来 改变 二级菜单新增按钮状态
const isTopDir = ref(false)

// 新增对话框开关
const addMenuDrawer = ref(false)
// 新增模式
const isTop = ref(true)
// 新增子菜单的父id和父名称
const addTwoPId = ref(-1)
const addTwoPName = ref('')
// 新增表单数据
const addForm = ref<Menu>({
  id: 0,
  menuName: '',
  parentId: 0,
  routerPath: '',
  routerName: '',
  componentPath: '',
  isRedirect: '0',
  redirectPath: '',
  menuType: '',
  permission: '',
  createBy: '',
  createTime: '',
  updateBy: '',
  updateTime: '',
  remark: '',
  sort: 0,
  isShow: '1',
  icon: '',
  children: []
})
const addFormRef = ref<FormInstance>()
// 菜单新增修改规则
const menuRules = reactive({
  parentId: { required: true, message: '' },
  menuType: { required: true, message: '' },
  menuName: { required: true, message: '' },
  permission: { required: true, message: '' },
  routerName: { required: true, message: '' },
  routerPath: { required: true, message: '' },
  componentPath: { required: true, message: '' },
  isRedirect: { required: true, message: '' },
  isShow: { required: true, message: '' },
  redirectPath: { required: true, message: '' },
  sort: { required: true, message: '', type: 'number' }
})

// 新增菜单按钮, 打开新增菜单, 并设置菜单类型
function addMenuBtn(type: string) {
  if (type === 'D') {
    isTop.value = true
    addForm.value.menuType = 'D'
    addForm.value.parentId = 0
  } else if (type === 'M') {
    isTop.value = false
    addForm.value.menuType = 'M'
    addForm.value.parentId = addTwoPId.value
  }
  addMenuDrawer.value = true
}

// 新增取消
function addCancel() {
  addMenuDrawer.value = false
  addForm.value = {
    id: 0,
    menuName: '',
    parentId: 0,
    routerPath: '',
    routerName: '',
    componentPath: '',
    isRedirect: '0',
    redirectPath: '',
    menuType: '',
    permission: '',
    createBy: '',
    createTime: '',
    updateBy: '',
    updateTime: '',
    remark: '',
    sort: 0,
    isShow: '1',
    icon: '',
    children: []
  }
}

// 新增提交
async function addSubmit(formR: FormInstance | undefined) {
  if (!formR) return
  await formR.validate((vaild: boolean) => {
    if (vaild) {
      addMenu(addForm.value).then((res) => {
        if (res.code === 200) {
          ElMessage({
            message: '新增成功',
            type: 'success'
          })
          addCancel()
          toGetMenuTree()
        }
      })
    } else {
      ElMessage({
        message: '请检查数据',
        type: 'warning'
      })
    }
  })
}
/**
 * 权限管理
 */
// 权限抽屉
const permDrawer = ref(false)
const permList = ref<Menu[]>([])

// 新增权限对话框
const addPermDialog = ref(false)
// 权限信息点击按钮, 获取权限列表
function permBtnClick(id: number) {
  permList.value.length = 0
  getPermsList(id).then((res) => {
    permList.value = res.data!
    permDrawer.value = true
  })
}
// 权限新增表单
const addPermForm = ref({
  parentId: 0,
  menuName: '',
  permission: ''
})
const addPermFormRule = reactive({
  menuName: { required: true, message: '请填写名称' },
  permission: { required: true, message: '请填写权限代码' }
})
// 权限新增取消
function addPermDialogCancel() {
  addPermDialog.value = false
  addPermForm.value = {
    parentId: 0,
    menuName: '',
    permission: ''
  }
}
// 权限新增提交
function addPermDialogSubmit() {
  addPermForm.value.parentId = editForm.value.id
  addPerm(addPermForm.value).then((res) => {
    if (res.code === 200) {
      ElMessage({
        message: '新增成功',
        type: 'success'
      })
      getPermsList(editForm.value.id).then((res) => {
        permList.value = res.data!
      })
      addPermDialog.value = false
      addPermForm.value = {
        parentId: 0,
        menuName: '',
        permission: ''
      }
    }
  })
}
// 权限删除
function permDelete(id: number) {
  ElMessageBox.confirm('确认删除选择的权限吗?', '删除权限', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'error'
  })
    .then(() => {
      deleterMenu(id).then((res) => {
        if (res.code === 200) {
          ElMessage({
            message: '删除成功',
            type: 'success'
          })
          getPermsList(editForm.value.id).then((res) => {
            permList.value = res.data!
          })
        }
      })
    })
    .catch(() => {})
}
// 权限编辑

const editPermDialog = ref(false)
const editPermForm = ref({
  id: 0,
  menuName: '',
  permission: ''
})
// 点击编辑按钮
function editPermBtn(row: any) {
  editPermDialog.value = true
  editPermForm.value = {
    id: row.id,
    menuName: row.menuName,
    permission: row.permission
  }
}

// 权限编辑取消
function editPermDialogCancel() {
  editPermDialog.value = false
  editPermForm.value = {
    id: 0,
    menuName: '',
    permission: ''
  }
}

function editPermDialogSubmit() {
  ElMessageBox.confirm('确认保存做出的修改吗??', '权限修改', {
    confirmButtonText: '确认',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(() => {
      updatePerm(editPermForm.value).then((res) => {
        if (res.code === 200) {
          ElMessage({
            message: '保存成功',
            type: 'success'
          })
          getPermsList(editForm.value.id).then((res) => {
            permList.value = res.data!
          })
          editPermDialog.value = false
          editPermForm.value = {
            id: 0,
            menuName: '',
            permission: ''
          }
        }
      })
    })
    .catch(() => {})
}
</script>

<style lang="scss" scoped>
.menu-container {
  height: 100%;
  display: grid;
  grid-template-columns: 3fr 8fr;
  column-gap: 15px;
  @media screen and (max-width: 1000px) {
    grid-template-columns: 1fr;
    row-gap: 20px;
  }
  .right {
    height: 100%;
    overflow-y: scroll;
  }
}
</style>
